#include <cstdlib>
#include <ctime>
#include "rclcpp/rclcpp.hpp"
#include "base_interfaces_demo/srv/patrol.hpp"
#include <chrono>
#include "rcl_interfaces/msg/parameter.hpp"
#include "rcl_interfaces/msg/parameter_value.hpp"
#include "rcl_interfaces/msg/parameter_type.hpp"
#include "rcl_interfaces/srv/set_parameters.hpp"
using namespace std::chrono_literals;
using base_interfaces_demo::srv::Patrol;
using rcl_interfaces::msg::Parameter;
using rcl_interfaces::msg::ParameterValue;
using rcl_interfaces::msg::ParameterType;
using SetP=rcl_interfaces::srv::SetParameters;
class TurtlePatrolClient:public rclcpp::Node
{
public:
    TurtlePatrolClient(const std::string &node_name):Node(node_name)
    {
        patrol_client_=this->create_client<Patrol>("patrol");
        timer_=this->create_wall_timer(10s,std::bind(
            &TurtlePatrolClient::timer_call_back,this));
        srand(time(NULL));  
    }
    void timer_call_back()
    {
        while(!patrol_client_->wait_for_service(1s))
        {
            if(!rclcpp::ok())
            {
                RCLCPP_ERROR(this->get_logger(),"等待服务过程中被打断...");
            }
            RCLCPP_INFO(this->get_logger(),"等待服务上线");
        }
        auto request=std::make_shared<Patrol::Request>();
        request->target_x=rand()%15;
        request->target_y=rand()%15;
        RCLCPP_INFO(this->get_logger(),"请求巡逻：{%f,%f}",
        request->target_x,request->target_y);
        patrol_client_->async_send_request(
            request,
            [&](rclcpp::Client<Patrol>::SharedFuture result_future)->void
            {
                auto response=result_future.get();
                if(response->result==Patrol::Response::SUCCESS)
                {
                    RCLCPP_INFO(this->get_logger(),"目标点处理成功");
                }
                else if(response->result==Patrol::Response::FALL)
                {
                    RCLCPP_INFO(this->get_logger(),"目标点处理失败");
                }
            }
            );
    }
    SetP::Response::SharedPtr call_set_parameters(Parameter&parameter)
    {
        auto param_client_=this->create_client<SetP>
        ("/turtle_patrol_client_node/set_parameters");
        while(!param_client_->wait_for_service(1s))
        {
            if(!rclcpp::ok())
            {
                RCLCPP_INFO(this->get_logger(),"等待服务的过程被打断...");
                exit(1);
            }
            RCLCPP_INFO(this->get_logger(),"等待参数设置服务端上线");
        }
        auto request=std::make_shared<SetP::Request>();
        request->parameters.push_back(parameter);
        auto future=param_client_->async_send_request(request);
        rclcpp::spin_until_future_complete(this->get_node_base_interface(),future);
        auto response=future.get();
        return response;
    }
    void update_server_param_key(double k)
    {
        auto param=Parameter();
        param.name="k";
        auto param_value=ParameterValue();
        param_value.type=ParameterType::PARAMETER_DOUBLE;
        param_value.double_value=k;
        param.value=param_value;
        auto response=call_set_parameters(param);
        if(response==nullptr)
        {
            RCLCPP_INFO(this->get_logger(),"修改参数失败");
            return;
        }
        else
        {
            for(auto result:response->results)
            {
                if(result.successful)
                {
                    RCLCPP_INFO(this->get_logger(),"参数k已修改为:%f",k);
                }
                else
                {
                    RCLCPP_WARN(this->get_logger(),"参数k修改失败原因:%s",
                    result.reason.c_str());
                }
            }
        }       
    }

private:
    rclcpp::TimerBase::SharedPtr timer_;
    rclcpp::Client<Patrol>::SharedPtr patrol_client_;    
};
int main(int argc,char*argv[])
{
    rclcpp::init(argc,argv);
    auto node=std::make_shared<TurtlePatrolClient>(
        "turtle_patrol_client_node");
    node->update_server_param_key(4.0);
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}
